﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using HRProject.Code.DTO;
using System.Collections.Generic;
using HRProject.Code.Common;

namespace HRProject.Code.DAO
{
    public class RecordTypeDAO : BaseDAO
    {
        public RecordTypeDAO()
            : base ()
        {
        }

        private List<BLRecordType> select()
        {
            List<BLRecordType> result = new List<BLRecordType>();
            List<BaseCondition> condition = new List<BaseCondition>();
            condition.Add(new BaseCondition("@id", Guid.Empty, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", string.Empty, ParameterDirection.Input));
            DataTable data = select("usp_SearchRecordTypes", condition);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                BLRecordType recordType = new BLRecordType();
                recordType.Id = (Guid)data.Rows[i]["RecordTypeId"];
                recordType.Name = (string)data.Rows[i]["RecordTypeName"];
                recordType.Parent = new BLRecordType();
                recordType.Parent.Id = (Guid)data.Rows[i]["ParentRecordTypeId"];
                recordType.Description = (string)data.Rows[i]["Description"];
                recordType.DataSignature = (long)data.Rows[i]["DataSignature"];
                recordType.CreateDate = (DateTime)data.Rows[i]["CreateDate"];
                recordType.CreateUserId = (Guid)data.Rows[i]["CreateUserId"];
                recordType.UpdateDate = (DateTime)data.Rows[i]["UpdateDate"];
                recordType.UpdateUserId = (Guid)data.Rows[i]["UpdateUserId"];
                result.Add(recordType);
            }
            return result;
        }

        public List<BLRecordType> Search(BLRecordType filter)
        {
            List<BLRecordType> result = new List<BLRecordType>();
            List<BaseCondition> condition = new List<BaseCondition>();
            condition.Add(new BaseCondition("@id", filter.Id,ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", filter.Name,ParameterDirection.Input));
            DataTable data = select("usp_SearchRecordTypes", condition);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                BLRecordType recordType = new BLRecordType();
                recordType.Id = (Guid)data.Rows[i]["RecordTypeId"];
                recordType.Name = (string)data.Rows[i]["RecordTypeName"];
                recordType.Parent = new BLRecordType();
                recordType.Parent.Id = (Guid)data.Rows[i]["ParentRecordTypeId"];
                recordType.Description = (string)data.Rows[i]["Description"];
                recordType.Content = (string)data.Rows[i]["PolicyContent"];
                recordType.DataSignature = (long)data.Rows[i]["DataSignature"];
                recordType.CreateDate = (DateTime)data.Rows[i]["CreateDate"];
                recordType.CreateUserId = (Guid)data.Rows[i]["CreateUserId"];
                recordType.UpdateDate = (DateTime)data.Rows[i]["UpdateDate"];
                recordType.UpdateUserId = (Guid)data.Rows[i]["UpdateUserId"];
                result.Add(recordType);
            }
            return result;
        }

        public int Insert(BLRecordType recordType, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", recordType.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@parentId", recordType.Parent.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", recordType.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_AddRecordType", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public int update(BLRecordType recordType)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            int errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", recordType.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", recordType.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_UpdateRecordType", condition);
            return result;
        }

        public int delete(BLRecordType recordType)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            int errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_DeleteRecordType", condition);
            return result;
        }

        public BLRecordType BuildTree(List<BLRecordType> list)
        {
            BLRecordType result = new BLRecordType();
            result.Id = Guid.Empty;
            result.Name = ContentProvider.GetString("GeneralRecordType");

            List<BLRecordType> tempList = new List<BLRecordType>();
            tempList.AddRange(list);

            while (tempList.Count > 0)
            {
                for (int i = 0; i < tempList.Count; i++)
                {
                    if (tempList[i].Id.Equals(result.Id))
                    {
                        result.Name = tempList[i].Name;
                        tempList.RemoveAt(i);
                        i--;
                    }
                    else
                    {
                        BLRecordType parent = FindParent(result, tempList[i].Parent.Id);
                        if (parent != null)
                        {
                            tempList[i].Parent = parent;
                            parent.Children.Add(tempList[i]);
                            tempList.RemoveAt(i);
                            i--;
                        }
                        else
                        {
                            tempList.Add(tempList[i]);
                            tempList.RemoveAt(i);
                            i--;
                        }
                    }
                }
            }

            return result;
        }

        private BLRecordType FindParent(BLRecordType node, Guid parentId)
        {
            if (parentId.Equals(node.Id))
            {
                return node;
            }
            foreach (BLRecordType child in node.Children)
            {
                BLRecordType temp = FindParent(child, parentId);
                if (temp != null)
                {
                    return temp;
                }
            }
            return null;
        }

        public int Rename(BLRecordType recordType, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", recordType.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_RenameRecordType", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public int Move(BLRecordType recordType, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@parentId", recordType.Parent.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_MoveRecordType", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public int Delete(BLRecordType recordType, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", recordType.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", recordType.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_DeleteRecordType", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public List<BLRecordTypeSetting> SearchSettings(BLRecordType filter)
        {
            List<BLRecordTypeSetting> result = new List<BLRecordTypeSetting>();
            List<BaseCondition> condition = new List<BaseCondition>();
            condition.Add(new BaseCondition("@id", filter.Id, ParameterDirection.Input));
            DataTable data = select("usp_SearchRecordSettings", condition);
            for (int i = 0; i < data.Rows.Count; i++)
            {
                BLRecordTypeSetting setting = new BLRecordTypeSetting();
                setting.Id = (Guid)data.Rows[i]["RecordTypeSettingId"];
                setting.Name = (string)data.Rows[i]["RecordTypeSettingName"];
                setting.Description = (string)data.Rows[i]["Description"];
                setting.InputType = (int)data.Rows[i]["InputType"];
                setting.InputValue = (string)data.Rows[i]["InputValue"];
                setting.DataSignature = (long)data.Rows[i]["DataSignature"];
                setting.UpdateDate = (DateTime)data.Rows[i]["UpdateDate"];
                setting.UpdateUserId = (Guid)data.Rows[i]["UpdateUserId"];
                result.Add(setting);
            }
            return result;
        }
        
        public int InsertSetting(BLRecordTypeSetting setting, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", setting.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", setting.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@typeId", setting.Type.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", setting.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@inputType", setting.InputType, ParameterDirection.Input));
            condition.Add(new BaseCondition("@inputValue", setting.InputValue, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", setting.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_AddRecordSetting", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public int DeleteSetting(BLRecordTypeSetting setting, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", setting.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", setting.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_DeleteRecordSetting", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }

        public int UpdateSetting(BLRecordTypeSetting setting, ref int errorCode)
        {
            List<BaseCondition> condition = new List<BaseCondition>();
            errorCode = 0;
            condition.Add(new BaseCondition("@id", setting.Id, ParameterDirection.Input));
            condition.Add(new BaseCondition("@name", setting.Name, ParameterDirection.Input));
            condition.Add(new BaseCondition("@description", setting.Description, ParameterDirection.Input));
            condition.Add(new BaseCondition("@inputType", setting.InputType, ParameterDirection.Input));
            condition.Add(new BaseCondition("@inputValue", setting.InputValue, ParameterDirection.Input));
            condition.Add(new BaseCondition("@updateUserId", BLAuthentication.CurrentUserId, ParameterDirection.Input));
            condition.Add(new BaseCondition("@dataSignature", setting.DataSignature, ParameterDirection.Input));
            condition.Add(new BaseCondition("@errorCode", errorCode, ParameterDirection.Output));
            int result = update("usp_UpdateRecordSetting", condition);
            errorCode = (int)condition[condition.Count - 1].ParamValue;
            return result;
        }
    }
}
